<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0" />
    <link rel="icon" href="<%= BASE_URL %>favicon.ico" />
    <title>Audio time Test</title>
  </head>
  <body>
    <noscript>
      <strong
        >We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work
        properly without JavaScript enabled. Please enable it to
        continue.</strong
      >
    </noscript>
    <div id="app">
      <canvas id="canvas" width="640" height="360"></canvas>
      <p>
        <button id="play">Play</button>
        <button id="pause">Pause</button>
        <button id="reset">reset</button>
        <button id="fakecpu">fake cpu task</button>
        <button id="fakegpu">fake canvas drawing task</button>
        <button id="meter">open audiometer</button>
        <button id="connect">connect</button>
        <button id="disconnect">disconnect</button>
      </p>
      <p id="cpu" style="background-color: #eee"></p>
      <p id="gpu" style="background-color: #bbb"></p>
      <p id="output"></p>
      <video
        controls
        id="v1"
        muted
        crossorigin="anonymous"
        proload="auto"
        src="http://172.16.0.205:86/buckets/u-02rsh6ok96f7up6j/2022/03/23/wwynvnrng9fc8466/d0f9d2c6f59a410caac882fdc6d34bb3.mp4"
      ></video>
      <video
        id="a1"
        crossorigin="anonymous"
        proload="auto"
        controls
        src="http://172.16.0.205:86/buckets/u-02rsh6ok96f7up6j/2022/03/23/wwynvnrng9fc8466/442df9e5908c42cda0612a48365deff6.mp3"
      ></video>
      <video
        id="a2"
        crossorigin="anonymous"
        proload="auto"
        controls
        src="http://172.16.0.205:86/buckets/u-02rsh6ok96f7up6j/2022/03/29/shea9x9s3fwo14na/0c73b67a9de04ec48303eea3b57e921d.mp3"
      ></video>
      <video
        id="a3"
        crossorigin="anonymous"
        proload="auto"
        controls
        src="http://172.16.0.205:86/buckets/u-02rsh6ok96f7up6j/20211025/2021-10-25/b025-%E5%9B%A0%E4%B8%BA%E6%9C%89%E4%BD%A0-4eed8b21b066114b_6619e8bcf780422cadc9f888d9568fae_low_audio1.mp3"
      ></video>
      <video
        id="a4"
        crossorigin="anonymous"
        proload="auto"
        controls
        src="http://172.16.0.205:86/buckets/u-02rsh6ok96f7up6j/20210506/2021-05-06/Source_16C5561a09f7b269741_0285051e0a884392b816fe587fb3d5ea_low_audio1.mp3"
      ></video>
      <video
        id="a5"
        crossorigin="anonymous"
        proload="auto"
        controls
        src="http://172.16.0.205:86/buckets/u-870j19o545i0q0z6/20211109/2021-11-09/b025-%E5%9B%A0%E4%B8%BA%E6%9C%89%E4%BD%A0-%E6%9C%97%E8%AF%B5%E7%89%88-%E6%96%B0122222_505fbdb099e94487bf77b1c5b3dd7572_low_audio1.mp3"
      ></video>
      <video
        id="a6"
        crossorigin="anonymous"
        proload="auto"
        controls
        src="http://172.16.0.205:86/buckets/u-870j19o545i0q0z6/20211109/2021-11-09/b025-%E5%9B%A0%E4%B8%BA%E6%9C%89%E4%BD%A0-%E6%9C%97%E8%AF%B5%E7%89%88-%E6%96%B014444444444444444_0687d35077274bed9581a553ec064db6_low_audio1.mp3"
      ></video>
      <video
        id="a7"
        crossorigin="anonymous"
        proload="auto"
        controls
        src="http://172.16.0.205:86/buckets/u-02rsh6ok96f7up6j/20220105/2022-01-05/WFG123new_95286d597b094cd29c1116879ebb0376_low_audio1.mp3"
      ></video>
      <video
        id="a8"
        crossorigin="anonymous"
        proload="auto"
        controls
        src="http://172.16.0.205:86/buckets/u-02rsh6ok96f7up6j/20210506/2021-05-06/Source_16C5561a09f7b269741_0285051e0a884392b816fe587fb3d5ea_low_audio2.mp3"
      ></video>
    </div>
    <script>
      const srcs = [
        'http://172.16.0.205:86/buckets/u-02rsh6ok96f7up6j/20210506/2021-05-06/Source_16C5561a09f7b269741_0285051e0a884392b816fe587fb3d5ea_low_audio2.mp3',
        'http://172.16.0.205:86/buckets/u-02rsh6ok96f7up6j/20210506/2021-05-06/Source_16C5561a09f7b269741_0285051e0a884392b816fe587fb3d5ea_low_audio1.mp3',
        'http://172.16.0.205:86/buckets/u-02rsh6ok96f7up6j/20210506/2021-05-06/Source_16C5561a09f7b269741_0285051e0a884392b816fe587fb3d5ea_low_audio3.mp3',
        'http://172.16.0.205:86/buckets/u-02rsh6ok96f7up6j/20210506/2021-05-06/Source_16C5561a09f7b269741_0285051e0a884392b816fe587fb3d5ea_low_audio4.mp3',
        'http://172.16.0.205:86/buckets/u-02rsh6ok96f7up6j/20210506/2021-05-06/Source_16C5561a09f7b269741_0285051e0a884392b816fe587fb3d5ea_low_audio5.mp3',
        'http://172.16.0.205:86/buckets/u-02rsh6ok96f7up6j/20210506/2021-05-06/Source_16C5561a09f7b269741_0285051e0a884392b816fe587fb3d5ea_low_audio6.mp3',
        'http://172.16.0.205:86/buckets/u-02rsh6ok96f7up6j/20210506/2021-05-06/Source_16C5561a09f7b269741_0285051e0a884392b816fe587fb3d5ea_low_audio7.mp3',
        'http://172.16.0.205:86/buckets/u-02rsh6ok96f7up6j/20210506/2021-05-06/Source_16C5561a09f7b269741_0285051e0a884392b816fe587fb3d5ea_low_audio8.mp3',
        'http://172.16.0.205:86/buckets/u-02rsh6ok96f7up6j/2022/03/23/wwynvnrng9fc8466/d0f9d2c6f59a410caac882fdc6d34bb3.mp4',
      ]
      // for (let i = 1; i < 9; i++) {
      //   srcs[i] =
      //     'http://172.16.0.205:86/buckets/u-02rsh6ok96f7up6j/20210506/2021-05-06/Source_16C5561a09f7b269741_0285051e0a884392b816fe587fb3d5ea_low_audio1.mp3'
      // }
      const eles = ['a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'a8', 'v1'].map(
        (i, index) => {
          let el = document.getElementById(i)
          el.src = srcs[index]
          return el
        }
      )
      const canvas = document.getElementById('canvas')
      const context = canvas.getContext('2d')
      document.getElementById('play').onclick = play
      document.getElementById('pause').onclick = pause
      document.getElementById('fakecpu').onclick = fakeCpu
      document.getElementById('fakegpu').onclick = fakeGpu
      document.getElementById('meter').onclick = openAudioMeter
      document.getElementById('reset').onclick = reset
      document.getElementById('connect').onclick = connect
      document.getElementById('disconnect').onclick = disconnect
      let lines = []
      const id = setInterval(() => {
        const timeStamp = 'Stamp:' + eles.map((i) => i.currentTime).join(' - ')
        const min = Math.min(...eles.map((i) => i.currentTime))
        const max = Math.max(...eles.map((i) => i.currentTime))
        const timeDiff =
          'Diff:' +
          eles
            .map((i) => (i.currentTime - eles[1].currentTime).toFixed(5))
            .join(' - ')
        const str =
          [timeStamp, timeDiff, 'Min:' + min, 'Max: ' + max].join('<br />') +
          '<br />'
        lines.push(str)
        if (lines.length > 10) {
          lines.shift()
        }
        document.getElementById('output').innerHTML = lines.join('<br />')
      }, 500)
      let played = false
      function play() {
        eles.map((i) => {
          i.play()
        })
        lines = []
        document.getElementById('output').innerHTML = ''
        played = true
      }
      function reset() {
        eles.map((i) => {
          i.currentTime = 0
        })
      }
      function pause() {
        eles.map((i) => {
          i.pause()
        })
        eles.map((i) => {
          i.currentTime = eles[0].currentTime
        })
        played = false
      }
      function fibonacci(n) {
        if (n == 1 || n == 2) {
          return 1
        }
        return fibonacci(n - 2) + fibonacci(n - 1)
      }
      function fakeCpu() {
        const t = new Date()
        cpuArr = []
        document.getElementById('cpu').innerHTML = 'fake Cpu Start:'
        fibonacci(40)
        document.getElementById('cpu').innerHTML =
          'fake Cpu End, time Spend: ' + (new Date() - t) + '<br />'
        const timeStamp = 'Stamp:' + eles.map((i) => i.currentTime).join(' - ')
        const min = Math.min(...eles.map((i) => i.currentTime))
        const max = Math.max(...eles.map((i) => i.currentTime))
        const timeDiff =
          'Diff:' +
          eles
            .map((i) => (i.currentTime - eles[0].currentTime).toFixed(5))
            .join(' - ')
        const str =
          [timeStamp, timeDiff, 'Min:' + min, 'Max: ' + max].join('<br />') +
          '<br />'
        document.getElementById('cpu').innerHTML += str
      }
      function draw() {
        return new Promise((resolve, reject) => {
          let rafId = -1
          const d = () => {
            const imageData = context.getImageData(0, 0, 640, 360)
            for (let i = 0; i < imageData.data.length / 4; i++) {
              imageData.data[i * 4] = Math.round(Math.random() * 255)
              imageData.data[i * 4 + 1] = Math.round(Math.random() * 255)
              imageData.data[i * 4 + 2] = Math.round(Math.random() * 255)
              imageData.data[i * 4 + 3] = 255
            }
            context.putImageData(imageData, 0, 0)
            rafId = requestAnimationFrame(d)
          }
          d()
          setTimeout(() => {
            cancelAnimationFrame(rafId)
            resolve()
          }, 1000)
        })
      }

      async function fakeGpu() {
        const t = new Date()
        cpuArr = []
        document.getElementById('gpu').innerHTML = 'fake Gpu Start:'
        await draw()
        document.getElementById('gpu').innerHTML =
          'fake Gpu End, time Spend:' + (new Date() - t) + '<br />'

        const timeStamp = 'Stamp:' + eles.map((i) => i.currentTime).join(' - ')
        const min = Math.min(...eles.map((i) => i.currentTime))
        const max = Math.max(...eles.map((i) => i.currentTime))
        const timeDiff =
          'Diff:' +
          eles
            .map((i) => (i.currentTime - eles[0].currentTime).toFixed(5))
            .join(' - ')
        const str =
          [timeStamp, timeDiff, 'Min:' + min, 'Max: ' + max].join('<br />') +
          '<br />'
        document.getElementById('gpu').innerHTML += str
      }

      function chain(audioContext, source, times) {
        for (let i = 0; i < times; i++) {
          const splitter = audioContext.createChannelSplitter(2)
          const audioMerger = audioContext.createChannelMerger(2)
          const gainNodeR = audioContext.createGain()
          splitter.connect(gainNodeR, 1)
          gainNodeR.connect(audioMerger, 0, 1)
          gainNodeR.gain.value = 1
          const gainNodeL = audioContext.createGain()
          splitter.connect(gainNodeL, 0)
          gainNodeL.connect(audioMerger, 0, 0)
          gainNodeL.gain.value = 1

          source.connect(splitter)
          source = audioMerger
          if (!firstSplitter) {
            firstSplitter = splitter
          }
        }
        return source
      }

      let elementSource
      let audioContext
      let firstSplitter
      function openAudioMeter() {
        audioContext = new AudioContext()
        eles.slice(0, 8).forEach((video) => {
          // splitter 1
          elementSource = audioContext.createMediaElementSource(video)
          const audioMerger = chain(audioContext, elementSource, 3)
          const processor = audioContext.createScriptProcessor(512, 2, 2)
          processor.onaudioprocess = function (event) {
            const bufL = event.inputBuffer.getChannelData(0)
            const bufR = event.inputBuffer.getChannelData(1)
          }
          audioMerger.connect(processor)
          processor.connect(audioContext.destination)
        })
      }

      function connect() {
        elementSource.disconnect()
        elementSource.connect(audioContext.destination)
      }

      function disconnect() {
        elementSource.disconnect()
        elementSource.connect(firstSplitter)
      }
    </script>
    <!-- built files will be auto injected -->
  </body>
</html>
